/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.core.context;


import io.iec.edp.caf.boot.context.CAFFrameworkContextHolder;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.boot.context.CAFBizContextHolder;
import io.iec.edp.caf.core.session.CafSession;
import io.iec.edp.caf.core.session.CafSessionContextHolder;
import io.iec.edp.caf.core.session.ICafSessionService;
import io.iec.edp.caf.i18n.api.LanguageService;
import io.iec.edp.caf.msu.api.ServiceUnitAwareService;
import io.iec.edp.caf.tenancy.api.ITenantService;
import io.iec.edp.caf.tenancy.api.context.RequestTenantContextHolder;
import io.iec.edp.caf.tenancy.api.context.RequestTenantContextInfo;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.util.Assert;

import java.time.OffsetDateTime;

/**
 * ICAFContextService 实现类
 * CAFContext已经提供出去被大量使用了，不宜再修改，桥接一把
 *
 * @author wangyandong
 */
@Slf4j
//todo 被com/inspur/edp/svc/cloudprint/devicemanager/config/DeviceManagerConfiguration依赖
public class CafContextServiceImpl implements ICAFContextService {
    private ITenantService tenantService = null;
    private ServiceUnitAwareService serviceUnitAware;
    private static final ThreadLocal<String> tlCurrentSU = new InheritableThreadLocal<>();

    /**
     * 私有构造函数，防止开发人员直接创建
     */
    public CafContextServiceImpl() {

    }

    /**
     * 获取当前的Session对象
     */

    public CafSession getCurrentSession() {
        return CafSessionContextHolder.getCurrentSession();
    }

    @Override
    public CafSession getCopyedCurrentSession() {
        return CafSessionContextHolder.getCopyedCurrentSession();
    }

    /**
     * 设置当前上下文Session
     * @param session
     */
    public void setCurrentSession(CafSession session) {
        Assert.notNull(session, "session can not be null");

        CafSessionContextHolder.setCurrentSession(session);
    }

    @Override
    public void setCurrentThreadPoolSession(CafSession session) {
        Assert.notNull(session, "session can not be null");

        CafSessionContextHolder.setCurrentThreadPoolSession(session);
    }

    /**
     * 清理当前session
     * 仅限在异步线程调用
     */

    public void clearSession(){
//        var threadname = Thread.currentThread().getName();
//        log.info("准备清理session操作："+threadname,new Exception());
        //http线程不做清理操作,否则会发生401
        //todo 这个http-nio的判断不准，广水上是io-5200-exec-94和o-5200-exec-120这种
//        if(threadname.contains("http-nio")==false){
//            log.info("清理session操作："+threadname,new Exception());
            CafSessionContextHolder.clearSession();
//        }
    }

    @Override
    public void clearCurrentThreadPoolSession() {
        CafSessionContextHolder.clearCurrentThreadPoolSession();
    }

    @Override
    public void setCurrentSessionLanguage(String language) {
        Assert.notNull(language,"language can not be null");

        LanguageService languageService = SpringBeanUtils.getBean(LanguageService.class);
        languageService.getEnabledLanguages().stream().anyMatch(lang -> lang.getCode().equals(language));
        CafSession session = CafSessionContextHolder.getCurrentSession();
        assert session != null;
        session.setLanguage(language);

        //重新设置session信息
        CafSessionContextHolder.setCurrentSession(session);

        ICafSessionService sessionService = SpringBeanUtils.getBean(ICafSessionService.class);
        sessionService.update(session);
    }

    /**
     * 获取业务Context
     */
    public BizContext getBizContext() {
        return CAFBizContextHolder.getCurrentContext().orElse(null);
    }


    /**
     * 获取框架Context
     */
    public FrameworkContext getFrameworkContext() {
        return CAFFrameworkContextHolder.getCurrentContext().orElse(null);
    }

    /**
     * 获取当前的BizContextId
     */
    public String getContextId() {
        BizContext context = this.getBizContext();
        if (context != null)
            return context.getId();
        return null;
    }


    /**
     * 获取当前SU编号
     */
    public String getCurrentSU() {
        return tlCurrentSU.get();
    }

    /**
     * 获取当前SU编号
     *
     * @param su
     */
    public void setCurrentSU(String su) {
        if(this.serviceUnitAware ==null)
            this.serviceUnitAware = SpringBeanUtils.getBean(ServiceUnitAwareService.class);
        //传入的su大小写存在与标准写法不一致的情况，匹配一下再设置
        String realSuName= su;
        if(su!=null && !"".equals(su)){
            realSuName = this.serviceUnitAware.getEnabledServiceUnits()
                .stream()
                .filter(d -> su.equalsIgnoreCase(d))
                .findFirst()
                .orElse(su);
        }
        tlCurrentSU.set(realSuName);
    }

    /**
     * 获取Session标识
     */
    public String getSessionId() {
        CafSession session = this.getCurrentSession();
        if (session == null)
            return null;
        return session.getId();
    }

    /**
     * 获取租户标识
     */
    public int getTenantId() {
        RequestTenantContextInfo tenantContextInfo = RequestTenantContextHolder.get();
        if (tenantContextInfo != null) {
            return tenantContextInfo.getTenantId();
        }

        CafSession session = this.getCurrentSession();
        if (session == null)
//            throw new RuntimeException("无效的Session");
            return -1;
        return session.getTenantId();
    }

    /**
     * 用户编号
     */
    public String getUserId() {
        CafSession session = this.getCurrentSession();
        if (session == null)
            return null;
        return session.getUserId();
    }

    /**
     * 获取实例编号
     */
    public String getAppCode() {
        return "pg01";
    }

    /**
     * 获取登录时间
     */
    public OffsetDateTime getLoginTime() {
        CafSession session = this.getCurrentSession();
        if (session == null)
            return null;
        return session.getCreationDate().toOffsetDateTime();
    }

    /**
     * 获取当前语言
     */
    public String getLanguage() {
        CafSession session = this.getCurrentSession();
        if (session == null)
            return null;
        return session.getLanguage();
    }

    /**
     * 获取系统当前时间
     */
    public OffsetDateTime getCurrentDateTime() {
        return OffsetDateTime.now();
    }

    /**
     * 获取租户服务
     */
    private ITenantService getTenantService() {
        if (this.tenantService == null) {
            ITenantService service = SpringBeanUtils.getBean(ITenantService.class);
            this.tenantService = service;
        }
        return this.tenantService;
    }
}
